// Copyright (c) 2022 Presto Labs Pte. Ltd.
// Author: lucasyoo

#pragma once

#include <utility>
#include <cmath>
#include <vector>
#include <glog/logging.h>

#include "coin2/strategy/hamm/hamm.pb.h"
#include "coin2/strategy/hamm/util.h"

namespace coin2::strategy::hamm {

using coin2::strategy::hamm::OrderQtyGeneratorConfig;

class OrderQtyGenerator {
 public:
  OrderQtyGenerator(const OrderQtyGeneratorConfig& config, double lot_size);
  void onBookFeed(
      const double& q,
      const std::pair<double, double>& optimal_bid_ask,
      const TradeCollector* fill_collector,
      const double& lot_size,
      const double& fill_num_hurdle);
  virtual void GenerateOrderQty() = 0;
  virtual void GeneratePrice(const std::pair<double, double>& optimal_bid_ask) = 0;

  // Getter
  std::vector<double>& BidPrices() { return bid_prices_; }
  std::vector<double>& AskPrices() { return ask_prices_; }
  std::vector<double>& BidQtys() { return bid_qtys_; }
  std::vector<double>& AskQtys() { return ask_qtys_; }
  
  const double& OrderQty() const { return order_qty_; }

 private:
  double order_qty_{0};
  bool is_order_decay_{true};
  double eta_{0};

  std::vector<double> bid_prices_;
  std::vector<double> ask_prices_;
  std::vector<double> bid_qtys_;
  std::vector<double> ask_qtys_;

};
//------------------------------------
// SingleOrderQtyGenerator: Just one orders per bid/ask
//------------------------------------
class SingleOrderQtyGenerator : public OrderQtyGenerator {
 public:
  SingleOrderQtyGenerator(const OrderQtyGeneratorConfig& config, double lot_size);

  void GenerateOrderQty() final;
  void GeneratePrice(const std::pair<double, double>& optimal_bid_ask) final;

};

//------------------------------------
// MultiOrderQtyGenerator: Just one orders per bid/ask
//------------------------------------
class MultiOrderQtyGenerator : public OrderQtyGenerator {
 public:
  MultiOrderQtyGenerator(const OrderQtyGeneratorConfig& config, double lot_size);
  void GenerateOrderQty() final;
  void GeneratePrice(const std::pair<double, double>& optimal_bid_ask) final;

 private:
  int64_t book_level_{1};
  double max_spread_bps_{0};
};

}  // namespace coin2::strategy::hamm
